<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>WebGL Point Example</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      canvas {
        margin: 50px auto 0;
        display: block;
        background: yellow;
      }
    </style>
  </head>
  <body>
    <canvas id="canvas" width="400" height="400"></canvas>
    <script>
      const canvas = document.getElementById('canvas')
      const gl = canvas.getContext('webgl')

      if (!gl) {
        alert('WebGL not supported in this browser')
        throw new Error('WebGL not supported')
      }
      // 修正顶点着色器源码
      const vsSource = `
              attribute vec4 aPosition;
              void main() {
                gl_Position = aPosition;
                gl_PointSize = 30.0;
              }
            `
      // 片元着色器
      const fsSource = `
              void main() {
                gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
              }
            `

      // initShader函数实现：初始化 WebGL 着色器程序
      function initShader(gl, vsSource, fsSource) {
        // compileShader 函数用于编译单个着色器
        function compileShader(type, source) {
          const shader = gl.createShader(type) // 创建着色器对象
          gl.shaderSource(shader, source) // 将着色器源代码传递给着色器对象
          gl.compileShader(shader) // 编译着色器源代码

          // 检查编译状态，如果编译失败，输出错误信息并删除着色器
          if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
            console.error('An error occurred compiling the shaders:', gl.getShaderInfoLog(shader))
            gl.deleteShader(shader)
            return null // 如果编译失败，返回 null
          }

          return shader // 如果编译成功，返回着色器对象
        }

        // 编译顶点着色器和片段着色器
        const vertexShader = compileShader(gl.VERTEX_SHADER, vsSource)
        const fragmentShader = compileShader(gl.FRAGMENT_SHADER, fsSource)

        // 如果任意一个着色器编译失败，返回 null
        if (!vertexShader || !fragmentShader) {
          return null
        }

        // 创建着色器程序并附加编译好的顶点着色器和片段着色器
        const shaderProgram = gl.createProgram()
        gl.attachShader(shaderProgram, vertexShader)
        gl.attachShader(shaderProgram, fragmentShader)
        gl.linkProgram(shaderProgram) // 链接着色器程序

        // 检查链接状态，如果链接失败，输出错误信息并删除着色器程序
        if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
          console.error('Unable to initialize the shader program:', gl.getProgramInfoLog(shaderProgram))
          gl.deleteProgram(shaderProgram)
          return null // 如果链接失败，返回 null
        }

        return shaderProgram // 如果链接成功，返回着色器程序对象
      }

      const program = initShader(gl, vsSource, fsSource)
      gl.useProgram(program)

      const aPosition = gl.getAttribLocation(program, 'aPosition')
      let x = 0
      setInterval(() => {
        x += 1
        if (x > 1.0) {
          x = 0 - 1
        }
        gl.vertexAttrib1f(aPosition, x)
        // gl.clear(gl.COLOR_BUFFER_BIT)
        gl.drawArrays(gl.POINTS, 0, 1)
      }, 2000)
    </script>
  </body>
</html>
